<template>
  <!--用户登录组件-->
  <el-dialog :visible.sync="loginIsShow"
             width="35%"
             top="20vh"
             custom-class="my-dialog"
             :close-on-click-modal="false"
             @closed="closeLoginDialog">
    <!-- title部分-->
    <div slot="title" class="dialog-header">
      <div class="web-icon">
        <div class="login-logo">
          <el-image
              :src="loadAssetsImage('logo.png')"
              fit="cover">
          </el-image>
        </div>
        <div class="login-cha">
          <font-awesome-icon icon="fas fa-times" class="times"/>
        </div>
        <div class="login-neteasy">
          <el-image
              :src="loadAssetsImage('neteamusic.png')"
              fit="cover">
          </el-image>
        </div>
      </div>
    </div>

    <div class="login-content">
      <!-- 登录类型选项卡切换-->
      <div class="login-type" @click="chooseLoginType">
        <div :class="passwordLoginClass" data-id="0">
          验证码登录
        </div>
        <div :class="qrcodeLoginClass" data-id="1">
          扫码登录
        </div>
      </div>
      <!-- 登录部分-->
      <div class="login">
        <!-- 验证码登录部分 -->
        <div class="login-phone" v-show="isPasswordLogin">
          <div class="login-phone-input">
            <!-- 国家编号-->
            <div class="login-country">
              <el-select v-model="vrCode.curChooseCountry" placeholder="请选择">
                <el-option
                    v-for="item in countryList"
                    :key="item.en"
                    :label="item.showCode"
                    :value="item.code">
                  <span style="float: left">{{ item.zh }}</span>
                  <span style="float: right; color: #8492a6; font-size: 13px">{{
                      item.showCode
                    }}</span>
                </el-option>
              </el-select>
            </div>
            <div class="phone">
              <el-input v-model="vrCode.phone"
                        placeholder="请输入手机号"
                        clearable>
              </el-input>
            </div>
          </div>
          <div class="verify-code">
            <div class="code-num">
              <el-input v-model="vrCode.qrcode"
                        placeholder="请输入验证码"
                        clearable>
              </el-input>
            </div>
            <div class="code-get">
              <el-button type="primary"
                         plain
                         round
                         :disabled="!vrCode.isGetCode"
                         @click="getVRCode">获取验证码<span v-show="!vrCode.isGetCode">({{
                  vrCode.codeSeconds
                }}s)</span>
              </el-button>
            </div>
          </div>
          <div class="phone-submit">
            <el-button type="primary"
                       round
                       class="submit-login"
                       @click="userVrCodeLogin">
              登录
            </el-button>
          </div>
        </div>
        <!-- 二维码登录部分-->
        <div class="qr-login" v-show="!isPasswordLogin">
          <div class="show-qr">
            <el-image
                :src="qrCode.qrCodeSvg"
                fit="cover">
              <div slot="error" class="image-slot">
                <i class="el-icon-picture-outline"></i>
              </div>
            </el-image>
          </div>
          <div class="qrcode-msg">
            {{ qrCode.qrCodeInformation }}
          </div>
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<script>
import {
  checkVrCode, getQRCodeStatus,
  getQRKey,
  getVrCode
} from "@/http";
import QRCode from 'qrcode'
import {SHOWLOGINFORM} from "@/http/constant";
import {mapState} from "vuex";
import {publicFun} from "@/mixin";
import {setCookie} from "@/http/tools";


export default {
  name: "Login",
  data() {
    return {
      loginIsShow: false,
      isPasswordLogin: false,
      vrCode: {
        phone: '',
        qrcode: '',
        curChooseCountry: '86',
        isGetCode: true,
        codeSeconds: 5
      },
      isGetCode: true,
      codeSeconds: 5,
      qrCode: {
        success: true,
        // 图片
        qrCodeSvg: '',
        // 二维码key
        qrKey: '',
        // 二维码状态
        qrCodeInformation: '打开网易云音乐APP扫码登录',
        qrCodeInterval: null,
      }
    }
  },
  mixins: [publicFun],
  created() {
    this.getQRCodeKey()
  },
  methods: {
    // 通过事件委托的形式监听选择了哪种切换方式
    chooseLoginType(e) {
      const id = Number(e.target.dataset.id)
      this.isPasswordLogin = id === 0
    },
    // 关闭对话框动画结束的事件
    closeLoginDialog() {
      this.loginIsShow = false
    },
    // 获取二维码key
    getQRCodeKey() {
      return getQRKey().then(res => {
        const {code, data: {unikey}} = res
        if (code === 200) {
          // 更新二维码的key
          this.$set(this.qrCode, 'qrKey', unikey)
          const text = `https://music.163.com/login?codekey=${unikey}`
          const options = {
            margin: 0,
            width: 192,
            color: {
              dark: '#335de8',
              light: '#00000000',
            },
            type: 'svg',
          }
          QRCode.toString(text, options)
              .then(svg => {
                this.$set(this.qrCode, 'qrCodeSvg', `data:image/svg+xml;utf8,${encodeURIComponent(
                    svg
                )}`)
              })
        }
      })
    },
    // 轮询二维码状态
    checkQRCodeStatus() {
      const {qrCode: {qrCodeInterval}} = this
      if (qrCodeInterval) {
        clearInterval(qrCodeInterval)
        this.$set(this.qrCode, 'qrCodeInterval', null)
      }
      // 轮询查询二维码状态
      this.$set(this.qrCode, 'qrCodeInterval', setInterval(() => {
        const {qrCode: {qrKey}} = this
        if (qrKey === '') {
          return
        }
        getQRCodeStatus(qrKey).then(res => {
          const {code, cookie} = res
          let msg = ''
          if (code === 800) {
            // 二维码过期重新生成
            this.getQRCodeKey()
            msg = '二维码已失效，请重新扫码'
          } else if (code === 801) {
            msg = '打开网易云音乐APP扫码登录'
          } else if (code === 802) {
            msg = '扫描成功，请在手机上确认登录'
          } else {
            msg = '登录成功，请稍等...'
            const result = {
              code: 200,
              cookie: cookie.replaceAll(' HTTPOnly', '')
            }
            this.handleLoginResponse(result)
          }
          this.$set(this.qrCode, 'qrCodeInformation', msg)
        })
      }, 1000))
    },
    // 处理请求返回的cookie
    handleLoginResponse(data) {
      if (!data) {
        return
      }
      const {code, cookie} = data
      if (code === 200) {
        setCookie(cookie)
        this.$store.dispatch('fetchUserProfile')
        this.loginIsShow = false
      }
    },
    // 发送验证码
    getVRCode() {
      const {curChooseCountry, phone} = this.vrCode
      getVrCode(phone, curChooseCountry).then(res => {
        console.log(res)
        const {code} = res
        if (code === 200) {
          this.$set(this.vrCode, 'isGetCode', false)
          this.$set(this.vrCode, 'codeSeconds', 5)
          const timer = setInterval(() => {
            const {codeSeconds} = this.vrCode
            if (codeSeconds === 0) {
              this.$set(this.vrCode, 'isGetCode', true)
              clearInterval(timer)
            }
            this.$set(this.vrCode, 'codeSeconds', codeSeconds - 1)
          }, 1000)
        }
      })
    },
    // 用户点击登录
    userVrCodeLogin() {
      const {curChooseCountry, phone, qrcode} = this.vrCode
      if (phone.trim() === '') {
        this.showTips('请输入手机号', 'warning')
      } else if (qrcode.trim() === '') {
        this.showTips('请先获取验证码', 'warning')
      } else {
        checkVrCode(phone.trim(), qrcode.trim(), curChooseCountry).then(res => {
          console.log(res)

        }, err => {
          this.showTips('登录失败，请重新登录', 'error')
        })
      }
    },
  },
  mounted() {
    // 点击登录时显示登录框
    this.$bus.$on(SHOWLOGINFORM, () => {
      this.loginIsShow = true
    })
  },
  computed: {
    ...mapState(['countryList']),
    // 密码登录类
    passwordLoginClass() {
      return {
        'login-type-active': this.isPasswordLogin
      }
    },
    // 二维码登录类
    qrcodeLoginClass() {
      return {
        'login-type-active': !this.isPasswordLogin
      }
    }
  },
  watch: {
    isPasswordLogin: {
      immediate: true,
      handler(newVal) {
        const {qrCode: {qrCodeInterval}} = this
        if (newVal) {
          if (qrCodeInterval) {
            clearInterval(qrCodeInterval)
            this.$set(this.qrCode, 'qrCodeInterval', null)
          }
        } else {
          // 开始轮询二维码状态
          this.checkQRCodeStatus()
        }
      }
    }
  }
}
</script>

<style scoped lang="less">
@import "../assets/less/common";

/deep/ .el-dialog.my-dialog {
  height: 45vh;
}

//弹框头部部分
.dialog-header {
  .web-icon {
    display: flex;
    justify-content: flex-start;
    align-items: center;

    .login-logo {
      .el-image {
        width: 3vw;
        height: 3vw;
      }
    }

    .login-cha {
      color: @metaphorFont;
      margin-left: 0.5vw;
      margin-right: .7vw;
    }

    .login-neteasy {
      .el-image {
        width: 2.5vw;
        height: 2.5vw;
      }
    }
  }
}


.login-content {
  width: 70%;
  margin: 0 auto;

  //登录类型的切换
  .login-type {
    display: flex;
    justify-content: space-around;
    margin: 0 auto;
    font-weight: 700;
    font-size: .8vw;
    color: black;
    background-color: #f5f5f5;
    border-radius: 10px;
    text-align: center;
    overflow: hidden;

    > div {
      flex: 1;
      padding: 12px 0;
      border-radius: 10px;
      transition: all .1s;

      &:hover {
        background-color: @bgColor;
        color: @mainColor;
        cursor: pointer;
      }
    }

    .login-type-active {
      background-color: @bgColor;
      color: @mainColor;
    }
  }

  //登录部分
  .login {
    margin-top: 6vh;

    .login-phone {
      //手机号部分
      .login-phone-input {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%;

        .login-country {
          > .el-select {
            width: 3.5vw;
          }
        }

        .phone {
          margin-left: 1vw;

          > .el-input {
            margin: 0;
            width: 13vw;
          }
        }
      }

      //验证码部分
      .verify-code {
        display: flex;
        justify-content: center;
        align-items: center;
        margin-top: 2vh;

        .code-num {
          > .el-input {
            width: 10.5vw;
            margin: 0;
          }
        }

        .code-get {
          margin-left: 1vw;

          > .el-button {
            width: 6vw;
          }
        }
      }

      .phone-submit {
        display: flex;
        justify-content: center;
        align-items: center;
        margin-top: 4vh;

        > .el-button {
          width: 17vw;
        }
      }
    }

    .qr-login {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;

      .show-qr {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 240px;
        height: 240px;
        background-color: @bgColor;
        border-radius: 25px;

        > .el-image {
          width: 192px;
          height: 192px;
        }
      }

      .qrcode-msg {
        font-size: .6vw;
        margin-top: 15px;
      }
    }
  }
}

</style>